package com.icinfo.cloud.provider.common.config;

import com.alibaba.fastjson.support.spring.GenericFastJsonRedisSerializer;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.annotation.Order;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceClientConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.connection.lettuce.LettucePoolingClientConfiguration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import java.time.Duration;

@EnableCaching
@Configuration
@Order(-1)
public class RedisConfig {
    @Value("${spring.zf_redis.port}")
    private int redisPort;

    @Value("${spring.zf_redis.timeout}")
    private int redisTimeout;

    @Value("${spring.zf_redis.database}")
    private int zfRedisDb;
    @Value("${spring.cf_redis.database}")
    private int cfRedisDb;

    @Value("${spring.zf_redis.timeout}")
    private int timeout;

    @Value("${spring.zf_redis.lettuce.pool.max-active}")
    private int maxActive;

    @Value("${spring.zf_redis.lettuce.pool.max-wait}")
    private int maxWait;

    @Value("${spring.zf_redis.lettuce.pool.max-idle}")
    private int maxIdle;

    @Value("${spring.zf_redis.lettuce.pool.min-idle}")
    private int minIdle;

    @Value("${spring.zf_redis.host}")
    private String zfHost;

    @Value("${spring.zf_redis.password}")
    private String zfPassword;

    @Value("${spring.cf_redis.host}")
    private String cfHost;

    @Value("${spring.cf_redis.password}")
    private String cfPassword;

    /**
     * Jedis数据源
     * @param redisHost
     * @param redisAuth
     * @return
     */
/*    public RedisConnectionFactory connectionJedisFactory(String redisHost, String redisAuth) {
        JedisPoolConfig poolConfig = new JedisPoolConfig();
        poolConfig.setMaxTotal(maxActive);
        poolConfig.setMaxIdle(maxIdle);
        poolConfig.setMaxWaitMillis(maxWait);
        poolConfig.setMinIdle(minIdle);
        poolConfig.setTestOnBorrow(true);
        poolConfig.setTestOnReturn(false);
        poolConfig.setTestWhileIdle(true);
        JedisClientConfiguration clientConfig = JedisClientConfiguration.builder()
                .usePooling().poolConfig(poolConfig).and().readTimeout(Duration.ofMillis(redisTimeout)).build();
        // 单点redis
        RedisStandaloneConfiguration redisConfig = new RedisStandaloneConfiguration();
        // 哨兵redis
        // RedisSentinelConfiguration redisConfig = new RedisSentinelConfiguration();
        // 集群redis
        // RedisClusterConfiguration redisConfig = new RedisClusterConfiguration();
        redisConfig.setHostName(redisHost);
        redisConfig.setPassword(RedisPassword.of(redisAuth));
        redisConfig.setPort(redisPort);
        redisConfig.setDatabase(redisDb);
        return new JedisConnectionFactory(redisConfig,clientConfig);
    }*/

    /**
     * 连接池、redis客户端配置
     * @return
     */
    public LettuceClientConfiguration Lettuce(){
        //连接池配置
        GenericObjectPoolConfig genericObjectPoolConfig =
                new GenericObjectPoolConfig();
        genericObjectPoolConfig.setMaxTotal(maxActive);
        genericObjectPoolConfig.setMaxWaitMillis(maxWait);
        genericObjectPoolConfig.setMaxIdle(maxIdle);
        genericObjectPoolConfig.setMinIdle(minIdle);

        //redis客户端配置
        LettucePoolingClientConfiguration.LettucePoolingClientConfigurationBuilder
                builder =  LettucePoolingClientConfiguration.builder().
                commandTimeout(Duration.ofSeconds(timeout));
        builder.poolConfig(genericObjectPoolConfig);
        return builder.build();
    }

    /**
     * Lettuce 数据源
     * @return
     */
    @Bean
    public RedisConnectionFactory zfConnection(){
        /* ========= 基本配置 ========= */
        //单机模式
        RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration(zfHost,redisPort);
        redisStandaloneConfiguration.setDatabase(zfRedisDb);
        redisStandaloneConfiguration.setPassword(zfPassword);
        /* ========= 连接池通用配置 ========= */
        LettuceConnectionFactory lettuceConnectionFactory = new LettuceConnectionFactory(redisStandaloneConfiguration,Lettuce());
        return lettuceConnectionFactory;
    }

    /**
     * Lettuce 数据源
     * @return
     */
    @Primary
    @Bean
    public RedisConnectionFactory cfConnection(){
        /* ========= 基本配置 ========= */
        //单机模式
        RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration(cfHost,redisPort);
        redisStandaloneConfiguration.setDatabase(cfRedisDb);
        redisStandaloneConfiguration.setPassword(cfPassword);
        /* ========= 连接池通用配置 ========= */
        LettuceConnectionFactory lettuceConnectionFactory = new LettuceConnectionFactory(redisStandaloneConfiguration,Lettuce());
        return lettuceConnectionFactory;
    }


    /**
     * 创建redisTemplate
     * @return
     */
    @Bean
    public RedisTemplate<String, String> redisTemplate() {
        StringRedisSerializer keySerializer = new StringRedisSerializer();
        RedisTemplate<String, String> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(zfConnection());
        redisTemplate.setKeySerializer(keySerializer);
        redisTemplate.setHashKeySerializer(keySerializer);
        //redisTemplate.setValueSerializer(valueSerializer);
        //redisTemplate.setHashValueSerializer(valueSerializer);
        // hash的value序列化方式采用fastJson
        redisTemplate.setHashValueSerializer(new GenericFastJsonRedisSerializer());
        // value序列化方式采用fastJson
        redisTemplate.setValueSerializer(new GenericFastJsonRedisSerializer());
        return redisTemplate;
    }

    /**
     * 创建redisTemplate
     * @return
     */
    @Bean
    public RedisTemplate<String, String> cfRedisTemplate() {
        StringRedisSerializer keySerializer = new StringRedisSerializer();
        RedisTemplate<String, String> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(cfConnection());
        redisTemplate.setKeySerializer(keySerializer);
        //redisTemplate.setValueSerializer(valueSerializer);
        redisTemplate.setHashKeySerializer(keySerializer);
        //redisTemplate.setHashValueSerializer(valueSerializer);

        // hash的value序列化方式采用fastJson
        redisTemplate.setHashValueSerializer(new GenericFastJsonRedisSerializer());
        // value序列化方式采用fastJson
        redisTemplate.setValueSerializer(new GenericFastJsonRedisSerializer());

        return redisTemplate;
    }

}
